package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"

	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/httphandler"
	dwr "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/dwr/v3"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/dwr/v3/model"
)

const (
	endpoint    = "endpoint"
	ak          = "access_key"
	sk          = "secret_key"
	projectId   = "projectId"
	functionUrn = "functionUrn"
	objectUrl   = "https://bucket.endpoint/example.jpg"
)

func CreateClient() *dwr.DwrClient {
	client := dwr.NewDwrClient(
		dwr.DwrClientBuilder().
			WithEndpoint(endpoint).
			WithCredential(
				basic.NewCredentialsBuilder().
					WithAk(ak).
					WithSk(sk).
					WithProjectId(projectId).
					Build()).
			WithHttpConfig(config.DefaultHttpConfig().
				WithIgnoreSSLVerification(true).
				WithHttpHandler(httphandler.NewHttpHandler().AddResponseHandler(func(response http.Response) {
					fmt.Println(response.Header)
				}))).
			Build())
	return client
}

func CreateWorkflow(client *dwr.DwrClient, workflowName string) error {
	payloadFilter := "$"
	supportAnonymous := true
	mode := model.GetCreateWorkflowRequestBodyModeEnum().EXPRESS
	description := "description"
	start := true
	templateCategory := "Others"
	actionMode := "SEQUENTIAL"
	endState := "End"

	createResponse, err := client.CreateWorkflow(&model.CreateWorkflowRequest{
		GraphName: workflowName,
		Body: &model.CreateWorkflowRequestBody{
			States: &[]model.State{{
				Type:      model.GetStateTypeEnum().END,
				StateName: endState,
			}, {
				Start:            &start,
				Type:             model.GetStateTypeEnum().OPERATION,
				PayloadFilterIn:  &payloadFilter,
				PayloadFilterOut: &payloadFilter,
				StateName:        "Custom",
				ActionMode:       &actionMode,
				Actions: &[]model.Action{{
					ActionName:             "Custom",
					ActionAgency:           "",
					Function:               functionUrn,
					FunctionTemplate:       "",
					ActionTemplateCategory: &templateCategory,
					InvocationMode:         "SYNC",
					Timeout:                30,
					PayloadFilter:          &payloadFilter,
					DynamicSource:          map[string]interface{}{},
				}},
				NextState: &endState,
			}},
			Description: &description,
			Mode:        &mode,
			ExpressConfig: &model.ExpressConfig{
				SupportAnonymous: &supportAnonymous,
			},
		},
	})
	if err != nil || createResponse.HttpStatusCode != http.StatusCreated {
		fmt.Printf("failed to create workflow, err: %#v, response: %#v", err, createResponse)
		return err
	}
	return nil
}

// 使用自定义算子创建工作流
func main() {
	// 1、构造client
	client := CreateClient()
	// 2、创建工作流
	workflowName := "workflow_create_by_sdk" + strconv.FormatInt(time.Now().Unix(), 10)
	err := CreateWorkflow(client, workflowName)
	if err != nil {
		fmt.Printf("failed to create workflow\n")
		return
	}
	// 3、触发工作流
	response, err := http.Get(fmt.Sprintf("%s?x-workflow-graph-name=%s", objectUrl, workflowName))
	if err != nil {
		fmt.Printf("failed to execute workflow: %s", err.Error())
		return
	}
	defer func() {
		err := response.Body.Close()
		if err != nil {
			fmt.Printf("failed to close res body\n")
		}
	}()
	data, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Printf("failed to read response, err: %s", err.Error())
		return
	}
	fmt.Printf("response: %s\n", string(data))
	return
}
